using System;
using System.Collections.Generic;
using System.Linq;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;

namespace ExcelTemplateEngine.OpenXML
{
    /// <summary>
    /// 基于OpenXML的工作簿实现
    /// </summary>
    public class OpenXMLWorkbook : IWorkbook
    {
        private readonly SpreadsheetDocument _document;
        private readonly WorkbookPart _workbookPart;
        private readonly List<IWorksheet> _worksheets;
        private OpenXMLSharedStringTable _sharedStrings = null!;
        private OpenXMLStylesheet _styles = null!;
        private OpenXMLDefinedNames _names = null!;
        
        /// <summary>
        /// 内部的SpreadsheetDocument对象
        /// </summary>
        internal SpreadsheetDocument Document => _document;
        
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="document">SpreadsheetDocument对象</param>
        public OpenXMLWorkbook(SpreadsheetDocument document)
        {
            _document = document ?? throw new ArgumentNullException(nameof(document));
            _workbookPart = _document.WorkbookPart ?? throw new ArgumentException("工作簿部件不存在");
            _worksheets = new List<IWorksheet>();
            
            LoadWorksheets();
        }
        
        /// <summary>
        /// 工作表集合
        /// </summary>
        public IList<IWorksheet> Worksheets => _worksheets;
        
        /// <summary>
        /// 定义的名称集合
        /// </summary>
        public IDefinedNames Names
        {
            get
            {
                if (_names == null)
                {
                    _names = new OpenXMLDefinedNames(_workbookPart);
                }
                return _names;
            }
        }
        
        /// <summary>
        /// 共享字符串表
        /// </summary>
        public ISharedStringTable SharedStrings
        {
            get
            {
                if (_sharedStrings == null)
                {
                    var sharedStringPart = _workbookPart.GetPartsOfType<SharedStringTablePart>().FirstOrDefault();
                    if (sharedStringPart == null)
                    {
                        sharedStringPart = _workbookPart.AddNewPart<SharedStringTablePart>();
                        sharedStringPart.SharedStringTable = new SharedStringTable();
                    }
                    _sharedStrings = new OpenXMLSharedStringTable(sharedStringPart);
                }
                return _sharedStrings;
            }
        }
        
        /// <summary>
        /// 样式表
        /// </summary>
        public IStylesheet Styles
        {
            get
            {
                if (_styles == null)
                {
                    var stylesPart = _workbookPart.WorkbookStylesPart;
                    if (stylesPart == null)
                    {
                        stylesPart = _workbookPart.AddNewPart<WorkbookStylesPart>();
                        stylesPart.Stylesheet = new Stylesheet();
                    }
                    _styles = new OpenXMLStylesheet(stylesPart);
                }
                return _styles;
            }
        }
        
        /// <summary>
        /// 内部的OpenXML文档对象
        /// </summary>
        public object InternalDocument => _document;
        
        /// <summary>
        /// 添加工作表
        /// </summary>
        /// <param name="name">工作表名称</param>
        /// <returns>新创建的工作表</returns>
        public IWorksheet AddWorksheet(string name)
        {
            if (string.IsNullOrEmpty(name))
                throw new ArgumentException("工作表名称不能为空", nameof(name));
                
            // 检查名称是否已存在
            if (_worksheets.Any(w => w.Name == name))
                throw new ArgumentException($"工作表名称 '{name}' 已存在", nameof(name));
                
            // 创建工作表部件
            var worksheetPart = _workbookPart.AddNewPart<WorksheetPart>();
            worksheetPart.Worksheet = new Worksheet(new SheetData());
            
            // 获取sheets集合
            var sheets = _workbookPart.Workbook.GetFirstChild<Sheets>();
            if (sheets == null)
            {
                sheets = new Sheets();
                _workbookPart.Workbook.AppendChild(sheets);
            }
            
            // 计算新的sheet ID
            uint sheetId = 1;
            if (sheets.Elements<Sheet>().Any())
            {
                sheetId = sheets.Elements<Sheet>().Max(s => s.SheetId!.Value) + 1;
            }
            
            // 创建sheet引用
            var sheet = new Sheet()
            {
                Id = _workbookPart.GetIdOfPart(worksheetPart),
                SheetId = sheetId,
                Name = name
            };
            sheets.Append(sheet);
            
            // 创建工作表对象
            var worksheet = new OpenXMLWorksheet(worksheetPart, name, this);
            _worksheets.Add(worksheet);
            
            return worksheet;
        }
        
        /// <summary>
        /// 获取工作表
        /// </summary>
        /// <param name="name">工作表名称</param>
        /// <returns>工作表对象，如果不存在则返回null</returns>
        public IWorksheet? GetWorksheet(string name)
        {
            return _worksheets.FirstOrDefault(w => w.Name == name);
        }
        
        /// <summary>
        /// 删除工作表
        /// </summary>
        /// <param name="name">工作表名称</param>
        /// <returns>是否删除成功</returns>
        public bool RemoveWorksheet(string name)
        {
            var worksheet = _worksheets.FirstOrDefault(w => w.Name == name);
            if (worksheet == null)
                return false;
                
            // 从sheets集合中移除
            var sheets = _workbookPart.Workbook.GetFirstChild<Sheets>();
            var sheet = sheets!.Elements<Sheet>().FirstOrDefault(s => s.Name == name);
            if (sheet != null)
            {
                sheet.Remove();
            }
            
            // 删除工作表部件
            var openXmlWorksheet = worksheet as OpenXMLWorksheet;
            if (openXmlWorksheet != null)
            {
                _workbookPart.DeletePart(openXmlWorksheet.WorksheetPart);
            }
            
            // 从列表中移除
            _worksheets.Remove(worksheet);
            
            return true;
        }
        
        /// <summary>
        /// 加载现有工作表
        /// </summary>
        private void LoadWorksheets()
        {
            var sheets = _workbookPart.Workbook.GetFirstChild<Sheets>();
            if (sheets == null)
                return;
                
            foreach (var sheet in sheets.Elements<Sheet>())
            {
                var worksheetPart = (WorksheetPart)_workbookPart.GetPartById(sheet.Id!);
                var worksheet = new OpenXMLWorksheet(worksheetPart, sheet.Name!, this);
                _worksheets.Add(worksheet);
            }
        }
        
        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            _document?.Dispose();
        }
    }
}